package com.fll.fangyiuser.service.impl;

import com.aliyun.oss.ServiceException;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fll.fangyicommon.entity.ResultOk;
import com.fll.fangyicommon.entity.user.Oss;
import com.fll.fangyicommon.entity.user.User;
import com.fll.fangyicommon.utils.JWTUtil;
import com.fll.fangyicommon.utils.TimeUtil;
import com.fll.fangyiuser.dao.LoginDao;
import com.fll.fangyiuser.service.LoginService;
import com.fll.fangyiuser.service.OssService;
import com.fll.fangyiuser.service.UserService;
import com.fll.fangyiuser.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * @author fll
 * @create 2023/2/24
 */
@Service
@Slf4j
public class LoginServiceImpl extends ServiceImpl<LoginDao, User> implements LoginService {

    @Autowired
    private LoginDao loginDao;

    @Autowired
    private OssService ossService;

    @Autowired
    private UserService userService;
    
    @Autowired
    private RedisUtil redisUtil;

    /**
     * 注册
     * @param user
     * @return
     */
    @Override
    public int register(User user){
        return loginDao.register(user);
    }

    /**
     * 验证手机号是否注册
     * @param phone
     * @return
     */
    @Override
    public Boolean verifyRegistered(String phone){
        User user = loginDao.verifyRegistered(phone);
        if (user != null){
            log.info("号码===>{},已经注册，直接登录",phone);
            return true;
        }
        log.info("号码===>{},没有注册",phone);
        return false;
    }


    /**
     * 1账号密码登录、验证码注册合并接口
     *  type: 0,账号密码登录
     *  type: 1,验证码注册
     * @param params
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultOk loginOrRegister(Map<String, String> params) throws JsonProcessingException {
        ResultOk<Object> ok = new ResultOk();
        Map<String, Object> map = new HashMap(4);
        String phone = params.get("phone");
        String pass = params.get("pass");
        String code = params.get("code");
        String type = params.get("type");
        boolean isExistPhone = redisUtil.haskey("+86" + phone);
        String codeStr = (String)redisUtil.getValue("+86" + phone);

        User user = null;
        if (type.equals("0") || type == "0"){ //登录
            if (pass != null){
                user = loginDao.login(phone, pass);
            }
            if (code != null){
                if (codeStr == null){
                    ok.setCode(503);
                    ok.setMsg("验证码已过期");
                    return ok;
                }
                if (!codeStr.equals(code)){
                    ok.setCode(503);
                    ok.setMsg("验证码错误");
                    return ok;
                }
                if (isExistPhone && codeStr.equals(code)){
                    user = loginDao.getUserByPhone(phone);
                }
            }
            if (user == null){
                ok.setCode(400);
                ok.setMsg("账号或密码有误");
                return ok;
            }
            //赋值用户oss图片
            user.setOss(ossService.selectOssByUserId(user.getUserId()));

        } else { //验证码注册
//            String codeStr = redisUtil.getValue(phone).toString();
            if (isExistPhone && (codeStr.equals(code) || codeStr == code)){
                user = new User();
                Integer userId = Integer.parseInt(phone.substring(7,11));
                user.setUserId(userId); //手机号后四位
                user.setUserPhone(phone);
                user.setUserPass(userId.toString()); //初始密码也是后四位
                user.setUserRegtime(TimeUtil.getString(new Date()));
                user.setNickName("用户" + userId);
                user.setSex("未知");
                user.setUserDescribe("这个人很懒，什么都没有留下！");
                int num1 = this.register(user);
                if (num1 == 0){
                    throw new ServiceException("开启事务处理，注册失败");
                }
                Oss oss = new Oss();
                oss.setUserId(userId);
                oss.setUserAvatarUrl("https://fangyi-img.oss-cn-shenzhen.aliyuncs.com/avatar.jpg"); // 默认
                oss.setUserBgUrl("https://fangyi-img.oss-cn-shenzhen.aliyuncs.com/background.jpg");
                int num2 = ossService.insertOss(oss);
                if (num2 == 0){
                    throw new ServiceException("开启事务处理，注册失败");
                }
                user.setOss(oss);
            } else {
                ok.setCode(503);
                ok.setMsg("验证码错误");
                return ok;
            }
        }
        //分配token
        String userStr = new ObjectMapper().writeValueAsString(user);
        String token = JWTUtil.createJWT(UUID.randomUUID().toString(), userStr, null);
        ok.setCode(200);
        ok.setMsg("登录成功");
        map.put("token", token);
        map.put("user", user);
        ok.setData(map);
        return ok;
    }

    /**
     * 根据手机号查询用户
     * @param phone
     * @return
     */
    @Override
    public User getUserByPhone(String phone) {
        User userByPhone = loginDao.getUserByPhone(phone);
        if (userByPhone != null) {
            log.info("查询用户信息成功===>{}", userByPhone);
            return userByPhone;
        }
        log.error("查询用户信息失败===>{}", userByPhone);
        return null;
    }

    /**
     * 重置密码
     * @param params
     * @return
     */
    @Override
    public ResultOk resetPasss(Map<String, String> params){
        String phone = params.get("phone");
        String pass = params.get("pass");
        String code = params.get("code");
        ResultOk<String> ok = new ResultOk<>();
        if (phone != null && pass != null && code != null){
            //获取缓存验证码
            boolean isExistPhone = redisUtil.haskey("+86" + phone);
            String oldCode = (String)redisUtil.getValue("+86" + phone);
            if (isExistPhone && code.equals(oldCode)){ // 验证码相同
                redisUtil.delKey("+86" + phone); // 清除验证码
                User user = this.getUserByPhone(phone);
                if (user == null){ // 用户未注册
                    ok.setCode(400);
                    ok.setMsg("手机号未注册");
                    return ok;
                }
                user.setUserPass(pass); //修改密码
                Integer num = userService.update(user);
                if (num != 0){
                    ok.setCode(200);
                    ok.setMsg("重置成功");
                    return ok;
                }
            } else {
                ok.setCode(400);
                ok.setMsg("验证码错误");
                return ok;
            }
        }
        ok.setCode(400);
        ok.setMsg("表单错误");
        return ok;
    }

}
